package whf.framework.datasource.impl;

import java.util.Collection;
import java.util.List;

import whf.framework.datasource.DataSourceException;
import whf.framework.entity.Entity;
import whf.framework.exception.AppException;
import whf.framework.exception.ServiceNotFoundException;
import whf.framework.meta.Meta;
import whf.framework.meta.MetaFactory;
import whf.framework.service.FindService;
import whf.framework.util.BeanFactory;
import whf.framework.util.ThreadContext;

/**
 * @author king
 * @modify 2007-12-12 下午11:32:52
 */
public class QueryServiceDataSource<E extends Entity> extends AbstractDataSource<E> {

	private Class<? extends Entity> boClass;
	private String queryString;
	private Object[] queryParameters;
	private int start;
	private int pageSize;
	private boolean loadLazy;
	
	public QueryServiceDataSource(Class<? extends Entity> boClass, String queryString, Object[] queryParameters, boolean loadLazy) {
		this.boClass = boClass;
		this.queryString = queryString;
		this.queryParameters = queryParameters;
		this.loadLazy = loadLazy;
		this.start = 0;
		this.pageSize = Integer.MAX_VALUE;
	}
	
	public QueryServiceDataSource(Class<? extends Entity> boClass, String queryString, Object[] queryParameters, boolean loadLazy, int start, int pageSize) {
		this.boClass = boClass;
		this.queryString = queryString;
		this.queryParameters = queryParameters;
		this.loadLazy = loadLazy;
		this.start = start;
		this.pageSize = pageSize;
	}
	
	// private functions
	private FindService getFindService() throws ServiceNotFoundException{
		return BeanFactory.getService(MetaFactory.findByModelClass(this.boClass));
	}
	
	/* (non-Javadoc)
	 * @see whf.framework.datasource.DataSource#getTotalRowCount()
	 */
	public int getTotalRowCount() throws DataSourceException {
		if(this.totalRowCount >= 0)
			return this.totalRowCount;
		if(this.start == 0 && this.pageSize == Integer.MAX_VALUE && this.dataCollection != null) {
			this.totalRowCount = this.dataCollection.size();
			return this.totalRowCount;
		}
		try{
			if(service == null)
				service = this.getFindService();
			this.totalRowCount = service.getRowCount(this.queryString, this.queryParameters);
			return this.totalRowCount;
		} catch(AppException e){
			throw new DataSourceException(e);
		}
	}

	/* (non-Javadoc)
	 * @see whf.framework.datasource.DataSource#find(int, int)
	 */
	public Collection<E> getDataSource() throws DataSourceException {
		if(this.dataCollection != null) 
			return this.dataCollection;
		try {
			if(service == null)
				service = this.getFindService();
			List<E> tmp = null;
			if(this.loadLazy) {
				if(this.queryParameters != null && this.queryParameters.length > 0) 
					tmp = service.findWithoutLazy(queryString, this.queryParameters, this.start, this.pageSize);
				else
					tmp = service.findWithoutLazy(queryString, this.start, this.pageSize);
			} else {
				if(this.queryParameters != null && this.queryParameters.length > 0) 
					tmp = service.list(queryString, this.queryParameters, this.start, this.pageSize);
				else
					tmp = service.list(queryString, this.start, this.pageSize);
			}
			this.dataCollection = tmp;
			return this.dataCollection;
		} catch(AppException e){
			throw new DataSourceException(e);
		}
	}
}
